//#define SDL_reinterpret_cast(type, expression) reinterpret_cast<type>(expression) // for older version of sdl

#include "SocketMessage.h"
#include <assert.h>
#include <sstream>

SocketMessage::SocketMessage()
{
	m_dataIndex = 0;
}

void SocketMessage::Clear()
{

}

const unsigned char* SocketMessage::GetData() const
{
	return m_chars.data();
}

const int SocketMessage::GetLength() const
{
	return m_chars.size();
}

bool SocketMessage::ReadFloat(float* result)
{
	if (m_chars.empty())
	{
		return false;
	}
	//int diff = m_chars.size() - m_dataIndex;
	//if (diff < sizeof(float))
	//{
	//	assert(0);
	//	return false;
	//}
	//float* f = (float*)(&(m_chars[m_dataIndex]));
	//m_dataIndex += sizeof(float);
	//*result = SDLNet_Read32(f);
	std::string* str = new std::string();
	if (!ReadString(str))
	{
		delete str;
		return false;
	}
	*result = (float)atof((str->c_str()));	
	delete str;

	return true;
}

bool SocketMessage::ReadInt(int* result)
{
	if (m_chars.empty())
	{
		return false;
	}

	int diff = m_chars.size() - m_dataIndex;
	if (diff < sizeof(int))
	{
		assert(0);
		return false;
	}
	int* i;

	i = (int*)(&(m_chars[m_dataIndex]));	
	*result = SDLNet_Read32(i);

	m_dataIndex += sizeof(int);
	
	return true;
}

bool SocketMessage::ReadString(std::string* result)
{
	if (m_chars.empty())
	{
		return false;
	}
	// get size of string
	
	int len = 0;
	if (!ReadInt(&len))
	{
		return false;
	}
	if (m_dataIndex + (len * sizeof(int)) > m_chars.size())
	{
		return false;
	}

	// get string contents
	for (int i = 0; i != len; i++)
	{
		int c = 0;
		if (!ReadInt(&c))
		{
			return false;
		}

		*result += (char)c;
	}
	//const unsigned char* i = &m_chars[m_dataIndex];
	//result->append(i, i + len);
	//std::string test(reinterpret_cast<const char*>(i + 4));
	//*result += test;
	return true;
}

void SocketMessage::WriteFloat(float data)
{
	//SDLNet_Write32(data, &data);
	//unsigned char* chars = (unsigned char*)(&data);
	//m_chars.insert(m_chars.end(), chars, chars + sizeof(float));
	std::string* str = new std::string();

	std::ostringstream oss;
	oss << data;
	*str = oss.str();


	WriteString(*str);

	delete str;
}

void SocketMessage::WriteInt(int data)
{
	SDLNet_Write32(data, &data);
	unsigned char* chars = (unsigned char*)(&data);
	m_chars.insert(m_chars.end(), chars, chars + sizeof(int));
}

void SocketMessage::WriteString(const std::string& data)
{
	// first save the size of the string then store the string
	// save size of string
	int len = data.size();
	WriteInt(len);
	//m_chars.insert(m_chars.end(), (int)data.size(), sizeof(int));

	// string contents
	for (int s = 0; s != data.size(); s++)
	{
		int num = data[s];
		SDLNet_Write32(num, &num);
		unsigned char* chars = (unsigned char*)(&num);
		m_chars.insert(m_chars.end(), chars, chars + (sizeof(unsigned char*)));
	}
}

void SocketMessage::Append(unsigned char* data, unsigned char* length)
{
	m_chars.insert(m_chars.end(), data, length);
}